import { ethers } from "ethers";
import {
  API_CONFIG,
  USDT_CONTRACT_ADDRESS,
  PIZZA_ADDRESS,
  PIZZA_NFT_ADDRESS
} from "./config";
import { userStore } from "../../stores/modules/user";
import moment from "moment";
import { PIZZA as PIZZAI } from "./typechain-types";
import { PizzaSpace } from "./typechain-types/contracts/pizzaspace_nft.sol";
export class Contract {
  static address = null;
  static provider: ethers.BrowserProvider;
  static wallet = null;
  static contract = null;

  static init() {
    this.setProvider();
  }

  static USDT = async () => {
    const contract = new ethers.Contract(
      USDT_CONTRACT_ADDRESS,
      API_CONFIG.USDT,
      this.provider
    );
    return contract.connect(await this.provider!.getSigner());
  };

  static PIZZA = async (): Promise<PIZZAI> => {
    const contract = new ethers.Contract(
      PIZZA_ADDRESS,
      API_CONFIG.PIZZA,
      this.provider
    );

    return contract.connect(await this.provider!.getSigner()) as PIZZAI;
  };

  static PIZZANFT = async (): Promise<PizzaSpace> => {
    const contract = new ethers.Contract(
      PIZZA_NFT_ADDRESS,
      API_CONFIG.ERC721,
      this.provider
    );
    return contract.connect(await this.provider!.getSigner()) as PizzaSpace;
  };
  // ----------------------------------------------------------------------------------------
  static async transferUSDT(account: string, amount: string) {
    const contract = new ethers.Contract(
      USDT_CONTRACT_ADDRESS,
      API_CONFIG.USDT,
      this.provider
    );
    const singer = contract.connect(await this.provider.getSigner());
    return new Promise(resolve => {
      (singer as any)
        .transfer(account, ethers.parseUnits(amount, 18))
        .then(() => {
          resolve({ message: "成功", code: 200 });
        })
        .catch(() => {
          resolve({ message: "失败", code: 500 });
        });
    });
  }

  static async signMessage() {
    let today = moment(moment().format("YYYY-MM-DD")).unix();
    const sign = await (window as any).ethereum.request({
      method: "personal_sign",
      params: [
        "welcome z at " + today,
        (window as any).ethereum.selectedAddress
      ]
    });

    userStore().updateSign(sign);
  }

  static setProvider() {
    if ((window as any).ethereum == null) {
      console.log("MetaMask not installed; using read-only defaults");
      // this.provider = ethers.getDefaultProvider()
    } else {
      this.provider = new ethers.BrowserProvider((window as any).ethereum);
    }
    this.address = (window as any).ethereum.selectedAddress;
  }

  static async balance(contract_address) {
    const contract = await new ethers.Contract(
      contract_address,
      API_CONFIG.USDT,
      this.provider
    );
    const bal = await contract.balanceOf(this.address);
    const decimal = await contract.decimals();
    return ethers.formatUnits(bal, decimal);
  }

  static async ownerOf(contract_address, tokenID) {
    const contract = await new ethers.Contract(
      contract_address,
      API_CONFIG.ERC721,
      this.provider
    );

    const bal = await contract.ownerOf(tokenID);
    return bal;
  }

  static async ERC721BalanceOf(contract_address: string) {
    const contract = await new ethers.Contract(
      contract_address,
      API_CONFIG.ERC721,
      this.provider
    );
    const count = await contract.balanceOf(this.address);
    return count;
  }

  static async pledgeNFT(tokenIDs: ethers.BigNumberish[]) {
    return new Promise(async (resolve, reject) => {
    
        const nft = await this.PIZZANFT();
        const hasApprove = await nft.isApprovedForAll(this.address,PIZZA_ADDRESS).catch((err)=>reject(err))

        if (!hasApprove) {
          await nft.setApprovalForAll(PIZZA_ADDRESS, true).catch((err)=>reject(err))
        }
        (await this.PIZZA()).pledgeNFT(tokenIDs).catch((err)=>reject(err))
        resolve;
      
    });
  }
}
